import { ref, toRef, toValue } from "vue";
import { useVueFlow } from "@vue-flow/core";
import { nextTick } from "vue";

let extraCarTimer = null;
export function useRunProcess({ graph: dagreGraph, cancelOnError = true }) {
  const { updateNodeData, getConnectedEdges } = useVueFlow();

  const graph = toRef(() => toValue(dagreGraph));

  const isRunning = ref(false);

  const executedNodes = new Set();

  const runningTasks = new Map();

  const upcomingTasks = new Set();

  // async function runNode(node) {
  //   if (executedNodes.has(node.id)) return;

  //   const incomers = getConnectedEdges(node.id).filter(
  //     conn => conn.target === node.id
  //   );

  //   // 等待上游动画完成
  //   await Promise.all(
  //     incomers.map(incomer => until(() => !incomer.data.isAnimating))
  //   );

  //   if (!isRunning.value) return;

  //   executedNodes.add(node.id);

  //   updateNodeData(node.id, {
  //     isRunning: true,
  //     isFinished: false,
  //     hasError: false
  //   });
  //   //规定点的运行时间
  //   await new Promise(resolve => setTimeout(resolve, Math.floor(Math.random() * 4000) + 10000));
  //   // await new Promise(resolve => setTimeout(resolve, 100));
  //   updateNodeData(node.id, {
  //     isRunning: false,
  //     isFinished: true,
  //     hasError: false
  //   });

  //   let children = graph.value.successors(node.id); // 🌟先拿一次
  //   console.log("children", children);

  //   if (children.length > 0) {
  //     await runNode({ id: children[0] }); // 只走第一个子节点，模拟一条路径上的小车
  //   }
  // }


  // async function run(nodes) {
  //   if (isRunning.value) {
  //     return;
  //   }

  //   reset(nodes);

  //   isRunning.value = true;

  //   const startingNodes = nodes.filter(
  //     node => graph.value.predecessors(node.id)?.length === 0
  //   );

  //   // await Promise.all(startingNodes.map(node => runNode(node, true)));
  //   await Promise.all(startingNodes.map(node => runNode(node)));

  //   // clear();
  //   console.log('✅ 当前一轮跑完，准备重新reset重新开始');

  //   reset(nodes); // ❗跑完一轮后，重置节点状态
  //   executedNodes.clear(); // ❗清空已经执行过的记录

  //   await nextTick(); // 等一帧，保证页面UI刷新
  //   // 🌟加延时，比如休息500ms
  //   await new Promise(resolve => setTimeout(resolve, 100));
  //   await run(nodes); // ❗递归继续跑下一轮
  // }
  async function runNode(node, carId) {
    const incomers = getConnectedEdges(node.id).filter(
      conn => conn.target === node.id
    );

    // 等待上游动画完成
    await Promise.all(
      incomers.map(incomer => until(() => !incomer.data.isAnimating))
    );

    if (!isRunning.value) return;

    updateNodeData(node.id, data => ({
      ...data,
      isRunning: true,
      isFinished: false,
      hasError: false,
      animatingCars: [...(data.animatingCars || []), carId] // 多车支持
    }));

    // 模拟加工时间
    await new Promise(resolve =>
      setTimeout(resolve, Math.floor(Math.random() * 4000) + 10000)
    );

    updateNodeData(node.id, data => ({
      ...data,
      animatingCars: (data.animatingCars || []).filter(id => id !== carId),
      isRunning: false,
      isFinished: true
    }));

    const children = graph.value.successors(node.id);
    if (children.length > 0) {
      await runNode({ id: children[0] }, carId); // 同一辆车继续跑下去
    }
  }

  async function run(nodes) {
    if (isRunning.value) return;

    isRunning.value = true;
    let carCounter = 0;

    const startingNodes = nodes.filter(
      node => graph.value.predecessors(node.id)?.length === 0
    );

    async function dispatchCar() {
      if (!isRunning.value) return;

      const carId = `car-${++carCounter}`;
      const startNode = startingNodes[0]; // 一条路径

      runNode(startNode, carId); // 不 await：允许同时多辆车

      setTimeout(dispatchCar, 50000); // 每 3 秒发一辆
    }

    dispatchCar();
  }

  function reset(nodes) {
    clear();

    for (const node of nodes) {
      updateNodeData(node.id, {
        isRunning: false,
        isFinished: false,
        hasError: false,
        isSkipped: false,
        isCancelled: false
      });
    }

  }

  async function stop() {
    isRunning.value = false;
    executedNodes.clear();
    upcomingTasks.clear();
  }

  function clear() {
    isRunning.value = false;
    executedNodes.clear();
    runningTasks.clear();
  }

  return { run, stop, reset, isRunning };
}

async function until(condition) {
  return new Promise(resolve => {
    const interval = setInterval(() => {
      if (condition()) {
        clearInterval(interval);
        // @ts-expect-error
        resolve();
      }
    }, 100);
  });
}



